home *** CD-ROM | disk | FTP | other *** search
/ Alles Voor Internet / Tout Pour Internet / alles voor internet.iso / MacInternet™ / Telnet / NCSA / tn3270 2.4d7 source / tn3270 / api.c < prev    next >
Text File  |  1992-04-17  |  31KB  |  1,312 lines

  1. /*
  2.  *  tn3270 for the Macintosh Source Code
  3.  *  Brown University Computing and Information Services
  4.  *  Version 2.4d7  April, 1992
  5.  *  Copyright (c) 1988, 1989, 1990, 1991, 1992 by Brown University and by
  6.  *  Peter John DiCamillo.
  7.  *
  8.  *  Permission is granted to any individual or institution to use, copy,
  9.  *  or redistribute the binary version of this software and its
  10.  *  documentation provided this notice and the copyright notices are
  11.  *  retained.  Permission is granted to any individual or non-profit
  12.  *  institution to use, copy, modify, or redistribute the source files
  13.  *  of this software provided this notice and the copyright notices are
  14.  *  retained.  This software may not be distributed for profit, either
  15.  *  in original form or in derivative works, nor can the source be
  16.  *  distributed to other than an individual or a non-profit institution.
  17.  *  Any  individual or group interested in seeing and/or using these
  18.  *  source files but who are prevented from doing so by the above
  19.  *  constraints should contact Don Wolfe, Assistant Vice-President for
  20.  *  Computer Systems at Brown University, (401) 863-7250, for possible
  21.  *  software licensing of the source developed at Brown.
  22.  *
  23.  *  Brown University and Peter John DiCamillo make no representations
  24.  *  about the suitability of this software for any purpose.
  25.  *
  26.  *  BROWN UNIVERSITY AND PETER JOHN DICAMILLO GIVE NO WARRANTY, EITHER
  27.  *  EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION PROVIDED,
  28.  *  INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND
  29.  *  WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE.
  30.  *
  31.  */
  32.  
  33. #if !defined(USEDUMP)
  34.     #include "maclib.h"
  35.     #include "termdef.h"
  36.     #include "tn3270funcs.h"
  37.     #include "globals.h"
  38. #else
  39.     #pragma load "tn3270DumpFile"
  40. #endif
  41.  
  42. #include "telnet.h"
  43. #include "sppc.h"
  44.  
  45. #pragma segment api
  46.  
  47. Handle rcvMessage, sndMessage;    /* handles to message buffers */
  48.  
  49. short fromrefnum;                /* data for last received message */
  50. unsigned short msgLength;
  51. unsigned long msgId, replyId;
  52. cnr *msgcp;
  53.  
  54. unsigned char sppc_sessname[8] = "GFTM1-1";
  55. unsigned char ppcsessname[] = "\ptn3270 #1 session 1";
  56. char apimsgkind;                /* 0 =    , 1 = SPPC */
  57. static unsigned long apimsgid = 0;
  58. long ppcsref;                    /* used by PPC instead of fromrefnum */
  59.  
  60. void apiregister(char session, cnr *cp)        /* register our API */
  61. {
  62. sppcregister(session, cp);                    /* SPPC driver */
  63. if (ppcavail) ppcregister(session, cp);        /* PPC Toolbox */
  64. }
  65.  
  66. void sppcregister(char session, cnr *cp)
  67. {
  68. static unsigned char smgrname[] = "GFTM1";
  69. short i;
  70. OSErr rc;
  71.  
  72. if (session == 0) {            /* session manager registration */
  73.     smgrname[4] = '1';
  74.     sppc_sessname[4] = '1';
  75.     for (i=0; i < 8; i++) {
  76.         rc = SPPCRegister(smgrname, &smgrrefnum);
  77.         if (rc == noErr) {
  78.             smgr_sppc = 1;
  79.             break;
  80.             }
  81.         else {
  82.             smgrname[4]++;
  83.             sppc_sessname[4]++;
  84.             }
  85.         }
  86.     if (smgr_sppc) {
  87.         if (rcvMessage == 0) rcvMessage = NewHandle((Size)128);
  88.         if (sndMessage == 0) sndMessage = NewHandle((Size)128);
  89.         if ((rcvMessage == 0) || (sndMessage == 0)) {
  90.             apideregister(0, 0);
  91.             stoperr(apisalrt, 0);
  92.             }
  93.         }
  94.     else if (rc == dupFNErr) {
  95.         stoperr(apinalrt, 0);            /* tell user about name problem */
  96.         }
  97.     }
  98. else if (smgr_sppc) {                /* session registration */
  99.     sppc_sessname[6] = '1';
  100.     for (i=0; i < 8; i++) {
  101.         rc = SPPCRegister(sppc_sessname, &(cp->sessrefnum));
  102.         if (rc == noErr) {
  103.             cp->sess_sppc = 1;
  104.             strcpy(cp->sppcname, sppc_sessname);
  105.             break;
  106.             }
  107.         else {
  108.             sppc_sessname[6]++;
  109.             }
  110.         }
  111.     if (!(cp->sess_sppc)) {
  112.         cp->sessrefnum = 0;
  113.         stoperr(apinalrt, cp);            /* tell user about name problem */
  114.         }
  115.     }
  116. }
  117.  
  118. void ppcregister(char session, cnr *cp)
  119. {
  120. static unsigned char smgrname[] = "\ptn3270 #1";
  121. short i;
  122. OSErr rc;
  123. PPCOpenPBRec openpb;
  124. PPCPortRec pr;
  125. PPCParamBlockPtr ipb;
  126. pascal void (*compproc)();
  127.  
  128. if (session == 0) {            /* session manager registration */
  129.     smgrname[9] = '1';
  130.     ppcsessname[9] = '1';
  131.     for (i=0; i < 8; i++) {
  132.         memset(&pr, 0, sizeof(PPCPortRec));
  133.         memcpy(pr.name, smgrname, 10);
  134.         pr.portKindSelector = ppcByString;
  135.         memcpy(pr.u.portTypeStr, "\ptn3270 Session Manager", 23);
  136.  
  137.         memset(&openpb, 0, sizeof(PPCOpenPBRec));
  138.         openpb.serviceType = ppcServiceRealTime;
  139.         openpb.portName = ≺
  140.         openpb.locationName = 0;
  141.         openpb.networkVisible = true;
  142.  
  143.         rc = PPCOpen(&openpb, false);
  144.         if (rc == noErr) {
  145.             smgrppc = 1;
  146.             smgrpref = openpb.portRefNum;
  147.             break;
  148.             }
  149.         else {
  150.             smgrname[9]++;
  151.             ppcsessname[9]++;
  152.             }
  153.         }
  154.     if (smgrppc) {
  155.         if (rcvMessage == 0) rcvMessage = NewHandle((Size)128);
  156.         if (sndMessage == 0) sndMessage = NewHandle((Size)128);
  157.         /* issue Inform for our new port */
  158.         ipb = newparamblock();
  159.         if ((ipb == 0) || (rcvMessage == 0) || (sndMessage == 0)) {
  160.             stoperr(ppcopenalrt, 0);
  161.             ppcderegister(0, 0);
  162.             return;
  163.             }
  164.         memset(ipb, 0, sizeof(PPCParamBlockRec));
  165.         compproc = informproc;
  166.         ipb->informParam.ioCompletion = (PPCCompProcPtr)compproc;
  167.         ipb->informParam.portRefNum = smgrpref;
  168.         ipb->informParam.autoAccept = false;
  169.         rc = PPCInform((PPCInformPBPtr)ipb, true);
  170.         if (rc != noErr) {
  171.             stoperr(ppcopenalrt, 0);
  172.             ppcderegister(0, 0);
  173.             }
  174.         }
  175.     else if (rc == -910) {
  176.         stoperr(ppcnamealrt, 0);    /* tell user about name problem */
  177.         }
  178.     else {
  179.         stoperr(ppcopenalrt, 0);    /* other problem */
  180.         }
  181.     }
  182. else if (smgrppc) {                /* session registration */
  183.     ppcsessname[19] = '1';
  184.     for (i=0; i < 8; i++) {
  185.         memset(&pr, 0, sizeof(PPCPortRec));
  186.         memcpy(pr.name, ppcsessname, 20);
  187.         pr.portKindSelector = ppcByString;
  188.         memcpy(pr.u.portTypeStr, "\ptn3270 Session", 15);
  189.  
  190.         memset(&openpb, 0, sizeof(PPCOpenPBRec));
  191.         openpb.serviceType = ppcServiceRealTime;
  192.         openpb.portName = ≺
  193.         openpb.locationName = 0;
  194.         openpb.networkVisible = true;
  195.  
  196.         rc = PPCOpen(&openpb, false);
  197.         if (rc == noErr) {
  198.             cp->sessppc = 1;
  199.             cp->sesspref = openpb.portRefNum;
  200.             p2cstr(ppcsessname);
  201.             strcpy(cp->ppcname, ppcsessname);
  202.             c2pstr(ppcsessname);
  203.             break;
  204.             }
  205.         else {
  206.             ppcsessname[19]++;
  207.             }
  208.         }
  209.     if (cp->sessppc) {
  210.         /* issue Inform for our new port */
  211.         ipb = newparamblock();
  212.         if (ipb == 0) {
  213.             stoperr(ppcnamealrt, cp);
  214.             ppcderegister(1, cp);
  215.             return;
  216.             }
  217.         memset(ipb, 0, sizeof(PPCParamBlockRec));
  218.         compproc = informproc;
  219.         ipb->informParam.ioCompletion = (PPCCompProcPtr)compproc;
  220.         ipb->informParam.portRefNum = cp->sesspref;
  221.         ipb->informParam.autoAccept = false;
  222.         rc = PPCInform((PPCInformPBPtr)ipb, true);
  223.         if (rc != noErr) {
  224.             stoperr(ppcnamealrt, cp);
  225.             ppcderegister(1, cp);
  226.             }
  227.         }
  228.     else {
  229.         cp->sesspref = 0;
  230.         stoperr(ppcnamealrt, cp);    /* tell user about name problem */
  231.         }
  232.     }
  233. }
  234.  
  235. pascal void informproc(PPCParamBlockPtr pb)
  236. {
  237. OSErr rc;
  238. pascal void (*compproc)();
  239. clientinfo * cip;
  240. PPCParamBlockPtr ipb;
  241. short i;
  242. cnr *cp;
  243. char cpok;
  244.  
  245. if ((rc=pb->informParam.ioResult) != noErr) {
  246.     disposparamblock(pb);
  247.     return;
  248.     }
  249.  
  250. /* determine owner of this session */
  251. cpok = false;
  252. if (smgrppc && (pb->informParam.portRefNum == smgrpref)) {
  253.     cp = 0;                            /* check for session manager */
  254.     cpok = true;
  255.     }
  256. else {
  257.     for (i=0; i < MAXSESSIONS; i++) {
  258.         cp = cplist[i];                /* check for session */
  259.         if (cp != 0) {
  260.             if (cp->sessppc && (pb->informParam.portRefNum == cp->sesspref)) {
  261.                 cpok = true;
  262.                 break;
  263.                 }
  264.             }
  265.         }
  266.     }
  267.  
  268. cip = 0;
  269. if (cpok) cip = newclientrec();
  270. if (cip == 0) {
  271.     compproc = disposproc;
  272.     pb->rejectParam.ioCompletion = (PPCCompProcPtr)compproc;
  273.     rc = PPCReject((PPCRejectPBPtr)pb, true);
  274.     }
  275. else {
  276.     cip->sessrefnum = pb->informParam.sessRefNum;
  277.     cip->userdata = pb->informParam.userData;
  278.     cip->servicetype = pb->informParam.serviceType;
  279.     cip->reqtype = pb->informParam.requestType;
  280.     cip->cp = cp;
  281.     compproc = accproc;
  282.     pb->acceptParam.ioCompletion = (PPCCompProcPtr)compproc;
  283.     rc = PPCAccept((PPCAcceptPBPtr)pb, true);
  284.     }
  285. if (!cpok) return;
  286. ipb = newparamblock();
  287. if (ipb == 0) {
  288.     return;
  289.     }
  290. memset(ipb, 0, sizeof(PPCParamBlockRec));
  291. compproc = informproc;
  292. ipb->informParam.ioCompletion = (PPCCompProcPtr)compproc;
  293. if (cp == 0) {
  294.     ipb->informParam.portRefNum = smgrpref;
  295.     }
  296. else {
  297.     ipb->informParam.portRefNum = cp->sesspref;
  298.     }
  299. ipb->informParam.autoAccept = false;
  300. rc = PPCInform((PPCInformPBPtr)ipb, true);
  301. }
  302.  
  303. pascal void accproc(PPCParamBlockPtr pb)
  304. {
  305. datainfo *dip;
  306. OSErr rc;
  307. pascal void (*compproc)();
  308.  
  309. if ((rc=pb->acceptParam.ioResult) != noErr) {
  310.     deletesession(pb->acceptParam.sessRefNum);
  311.     disposparamblock(pb);
  312.     return;
  313.     }
  314. dip = newdatablock();
  315. if (dip == 0) {
  316.     compproc = disposproc;
  317.     pb->endParam.ioCompletion = (PPCCompProcPtr)compproc;
  318.     rc = PPCEnd((PPCEndPBPtr)pb, true);
  319.     deletesession(pb->acceptParam.sessRefNum);
  320.     return;
  321.     }
  322. memset(dip, 0, sizeof(datainfo));
  323. compproc = readproc;
  324. pb->readParam.ioCompletion = (PPCCompProcPtr)compproc;
  325. pb->readParam.bufferLength = 128;
  326. pb->readParam.bufferPtr = dip->msg;
  327. rc = PPCRead((PPCReadPBPtr)pb, true);
  328. }
  329.  
  330. pascal void readproc(PPCParamBlockPtr pb)
  331. {
  332. datainfo *dip;
  333. OSErr rc;
  334. pascal void (*compproc)();
  335. unsigned char *s;
  336.  
  337. if ((rc=pb->readParam.ioResult) != noErr) {
  338.     deletesession(pb->acceptParam.sessRefNum);
  339.     disposparamblock(pb);
  340.     return;
  341.     }
  342. s = (unsigned char *)pb->readParam.bufferPtr;
  343. s -= 22;
  344. dip = (datainfo *)s;
  345. dip->length = pb->readParam.actualLength;
  346. dip->userdata = pb->readParam.userData;
  347. dip->creator = pb->readParam.blockCreator;
  348. dip->type = pb->readParam.blockType;
  349. dip->sessrefnum = pb->readParam.sessRefNum;
  350. dip->more = pb->readParam.more;
  351. dip->incoming = 1;
  352.  
  353. dip = newdatablock();
  354. if (dip == 0) {
  355.     compproc = disposproc;
  356.     pb->endParam.ioCompletion = (PPCCompProcPtr)compproc;
  357.     rc = PPCEnd((PPCEndPBPtr)pb, true);
  358.     deletesession(pb->acceptParam.sessRefNum);
  359.     return;
  360.     }
  361. memset(dip, 0, sizeof(datainfo));
  362. compproc = readproc;
  363. pb->readParam.ioCompletion = (PPCCompProcPtr)compproc;
  364. pb->readParam.bufferLength = 128;
  365. pb->readParam.bufferPtr = dip->msg;
  366. rc = PPCRead((PPCReadPBPtr)pb, true);
  367. }
  368.  
  369. pascal void disposproc(PPCParamBlockPtr pb)
  370. {
  371. disposparamblock(pb);
  372. }
  373.  
  374. void deletesession(long refnum)
  375. {
  376. clientrec *cp;
  377.  
  378. cp = (clientrec *)clientqueue.first;
  379. while (cp != 0) {
  380.     if (cp->header.inuse) {
  381.         if (cp->client.sessrefnum == refnum) {
  382.             disposclientrec(&(cp->client));
  383.             return;
  384.             }
  385.         }
  386.     cp = (clientrec *)cp->header.next;        
  387.     }
  388. }
  389.  
  390. void apideregister(char session, cnr *cp)        /* cancel API registration */
  391. {
  392. sppcderegister(session, cp);            /* SPPC driver */
  393. ppcderegister(session, cp);                /* PPC Toolbox */
  394. if (cp != 0) cp->apiwritenotify = 0;
  395. }
  396.  
  397. void sppcderegister(char session, cnr *cp)
  398. {
  399. /* deregister session, if any */
  400. if (cp != 0) {
  401.     if (cp->sess_sppc) {
  402.         SPPCDeRegister(cp->sessrefnum);
  403.         cp->sess_sppc = 0;
  404.         }    
  405.     }
  406.  
  407. /* return if just session wanted */
  408. if (session) return;
  409.  
  410. /* deregister session manager */
  411. if (smgr_sppc) {
  412.     SPPCDeRegister(smgrrefnum);
  413.     smgr_sppc = 0;
  414.     }
  415. }
  416.  
  417. void ppcderegister(char session, cnr *cp)
  418. {
  419. PPCClosePBRec closepb;
  420. OSErr rc;
  421.  
  422. /* deregister session, if any */
  423. if (cp != 0) {
  424.     if (cp->sessppc) {
  425.         memset(&closepb, 0, sizeof(PPCClosePBRec));
  426.         closepb.portRefNum = cp->sesspref;
  427.         rc = PPCClose(&closepb, false);
  428.         cp->sessppc = 0;
  429.         }    
  430.     }
  431.  
  432. /* return if just session wanted */
  433. if (session) return;
  434.  
  435. /* deregister session manager */
  436. if (smgrppc) {
  437.     memset(&closepb, 0, sizeof(PPCClosePBRec));
  438.     closepb.portRefNum = smgrpref;
  439.     rc = PPCClose(&closepb, false);
  440.     smgrppc = 0;
  441.     }
  442. }
  443.  
  444. void apinewmsg(void)
  445. {
  446. OSErr rc;
  447. datarec *dp;
  448. short i;
  449. clientrec *cp;
  450. char cpok;
  451.  
  452. if (smgr_sppc) {
  453.     apimsgkind = 1;
  454.  
  455.     msgcp = 0;                    /* session manager */
  456.     rc = SPPCGet(smgrrefnum, &fromrefnum, 0, rcvMessage, &msgLength,
  457.                 &msgId, &replyId);
  458.     if (rc == noErr) smgrmsg();
  459.     
  460.                                 /* sessions */
  461.     for (i=0; i < MAXSESSIONS; i++) {
  462.         msgcp = cplist[i];
  463.         if (msgcp != 0) {
  464.             if (msgcp->sess_sppc) {
  465.                 rc = SPPCGet(msgcp->sessrefnum, &fromrefnum, 0, rcvMessage,
  466.                              &msgLength, &msgId, &replyId);
  467.                 if (rc == noErr) sessmsg();
  468.                 }
  469.             }
  470.         }
  471.     }
  472.  
  473. if (ppcavail) {
  474.     apimsgkind = 0;
  475.     dp = (datarec *)dataqueue.first;
  476.     while (dp != 0) {
  477.         if (dp->header.inuse) {
  478.             if (dp->data.incoming) {
  479.                 ppcsref = dp->data.sessrefnum;
  480.                 memcpy(*rcvMessage, dp->data.msg, dp->data.length);
  481.                 msgLength = dp->data.length;
  482.                 msgId = dp->data.userdata;
  483.                 replyId = dp->data.creator;
  484.                 cpok = false;    /* find client record to get msgcp */
  485.                 cp = (clientrec *)clientqueue.first;
  486.                 while (cp != 0) {
  487.                     if (cp->header.inuse) {
  488.                         if (cp->client.sessrefnum == ppcsref) {
  489.                             msgcp = cp->client.cp;
  490.                             cpok = true;
  491.                             break;
  492.                             }
  493.                         }
  494.                     cp = (clientrec *)cp->header.next;        
  495.                     }
  496.                 if (cpok) {
  497.                     if (msgcp == 0) {
  498.                         smgrmsg();
  499.                         }
  500.                     else {
  501.                         sessmsg();
  502.                         }
  503.                     }
  504.                 disposdatarec(&(dp->data));
  505.                 }
  506.             }
  507.         dp = (datarec *)dp->header.next;        
  508.         }
  509.     }
  510. }
  511.  
  512. void smgrmsg(void)
  513. {
  514. short **msgh;
  515.  
  516. msgh = (short **)rcvMessage;
  517. if (msgLength < 2) {
  518.     senderr(smgrrefnum, badRequestLength);
  519.     return;
  520.     }
  521.  
  522. switch (**msgh) {
  523.     case GetIdRequestType:
  524.                 if (msgLength != sizeof(GetIdRequest)) {
  525.                     senderr(smgrrefnum, badRequestLength);
  526.                     return;
  527.                     }
  528.                 sendid();
  529.                 break;
  530.     case GetCapRequestType:
  531.                 if (msgLength != sizeof(GetCapRequest)) {
  532.                     senderr(smgrrefnum, badRequestLength);
  533.                     return;
  534.                     }
  535.                 sendcap();
  536.                 break;
  537.     case GetVersRequestType:
  538.                 if (msgLength != sizeof(GetVersRequest)) {
  539.                     senderr(smgrrefnum, badRequestLength);
  540.                     return;
  541.                     }
  542.                 sendvers();
  543.                 break;
  544.     case OpenRequestType:
  545.                 if (msgLength != sizeof(OpenRequest)) {
  546.                     senderr(smgrrefnum, badRequestLength);
  547.                     return;
  548.                     }
  549.                 apiopensess();
  550.                 break;
  551.     case GetConnStatusType:
  552.                 if (msgLength != sizeof(GetConnStatus)) {
  553.                     senderr(smgrrefnum, badRequestLength);
  554.                     return;
  555.                     }
  556.                 sendconnstat();
  557.                 break;
  558.     default:
  559.                 senderr(smgrrefnum, badMessageType);
  560.                 break;
  561.     }
  562. }
  563.  
  564. void senderr(short myref, short code)
  565. {
  566. ErrorResponse er;
  567. OSErr rc;
  568. unsigned long respid;
  569.  
  570. er.msgtype = ErrorResponseType;
  571. er.code = code;
  572. memcpy(*sndMessage, &er, sizeof(ErrorResponse));
  573. rc = apisend(myref, fromrefnum, msgId, sndMessage, sizeof(ErrorResponse),
  574.              &respid);
  575. }
  576.  
  577. void sendcap(void)
  578. {
  579. GetCapResponse gcr;
  580. OSErr rc;
  581. unsigned long respid;
  582.  
  583. gcr.msgtype = GetCapResponseType;
  584. getsesscount(&gcr.pendsessions, &gcr.currsessions);
  585. gcr.maxsessions = MAXSESSIONS;
  586. gcr.numbformats = 1;
  587. gcr.sizeinfo[0].ptsize = 9;
  588. gcr.sizeinfo[0].rows = rowmax9;
  589. gcr.sizeinfo[0].cols = colmax9;
  590. if ((rowmax12 >= 24) && (colmax12 >= 80)) {
  591.     gcr.numbformats = 2;
  592.     gcr.sizeinfo[1].ptsize = 12;
  593.     gcr.sizeinfo[1].rows = rowmax12;
  594.     gcr.sizeinfo[1].cols = colmax12;
  595.     }
  596. memcpy(*sndMessage, &gcr, sizeof(GetCapResponse));
  597. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage, 
  598.              sizeof(GetCapResponse), &respid);
  599. }
  600.  
  601. void getsesscount(short *pend, short *curr)
  602. {
  603. short i;
  604. cnr *cp;
  605.  
  606. (*pend) = (*curr) = 0;
  607. for (i=0; i < MAXSESSIONS; i++) {
  608.     cp = cplist[i];
  609.     if (cp != 0) {
  610.         if (cp->sess_sppc || cp->sessppc) {
  611.             (*curr)++;
  612.             }
  613.         else {
  614.             (*pend)++;
  615.             }
  616.         }
  617.     }
  618. }
  619.  
  620. void sendvers(void)
  621. {
  622. GetVersResponse gvr;
  623. OSErr rc;
  624. unsigned long respid;
  625. Handle version;
  626. Size vsize;
  627.  
  628. memset(&gvr, 0, sizeof(GetVersResponse));
  629. gvr.msgtype = GetVersResponseType;
  630. version = GetResource('vers', 1);
  631. if (version != 0) {
  632.     vsize = GetHandleSize(version);
  633.     if (vsize > 120) vsize = 120;
  634.     memcpy(gvr.versdata, *version, vsize);
  635.     }
  636. memcpy(*sndMessage, &gvr, vsize+8);
  637. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage, vsize+8, &respid);
  638. }
  639.  
  640. void sendid(void)
  641. {
  642. GetIdResponse gir;
  643. OSErr rc;
  644. unsigned long respid;
  645. unsigned char apName[256];
  646. short apRefNum;
  647. Handle apParam;
  648. short namelen;
  649.  
  650. memset(&gir, 0, sizeof(GetIdResponse));
  651. gir.msgtype = GetIdResponseType;
  652. gir.signature = 'GFTM';
  653. GetAppParms(apName, &apRefNum, &apParam);
  654. p2cstr(apName);
  655. gir.refnum = apRefNum;
  656. namelen = strlen(apName);
  657. namelen++;
  658. if (namelen > 120) namelen = 120;
  659. memcpy(gir.appname, apName, namelen);
  660. memcpy(*sndMessage, &gir, namelen+12);
  661. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage, namelen+12, &respid);
  662. }
  663.  
  664. void apiopensess(void)
  665. {
  666. unsigned short len;
  667. short pend, curr;
  668. char fmtok;
  669. OpenResponse or;
  670. OSErr rc;
  671. unsigned long respid;
  672.  
  673. /* check that a session can be opened now */
  674. getsesscount(&pend, &curr);
  675. if ((pend + curr) == MAXSESSIONS) {
  676.     memset(&or, 0, sizeof(OpenResponse));
  677.     or.msgtype = OpenResponseType;
  678.     or.code = openNoSessions;
  679.     memcpy(*sndMessage, &or, sizeof(OpenResponse));
  680.     rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
  681.                  sizeof(OpenResponse), &respid);
  682.     return;
  683.     }
  684.  
  685. /* copy open session request data */
  686. memcpy(&apiopenreq, *rcvMessage, sizeof(OpenRequest));
  687.  
  688. /* copy host name */
  689. len = strlen(apiopenreq.hostname);
  690. if (len > 255) len = 255;
  691. memcpy(apihostname, apiopenreq.hostname, len+1);
  692. apihostname[len] = 0;
  693. apiopenreq.hostname = apihostname;
  694.  
  695. /* copy window name */
  696. len = strlen(apiopenreq.windowname);
  697. if (len > 255) len = 255;
  698. memcpy(apiwindowname, apiopenreq.windowname, len+1);
  699. apiwindowname[len] = 0;
  700. apiopenreq.windowname = apiwindowname;
  701.  
  702. /* copy request message information */
  703. apiopenrefnum = fromrefnum;
  704. apiopenmsgid = msgId;
  705. apiopenkind = apimsgkind;
  706. apiopensref = ppcsref;
  707.  
  708. /* check the requested screen sizes are valid */
  709. fmtok = 1;
  710. if (apiopenreq.dfltsize.rows != 24) fmtok = 0;
  711. if (apiopenreq.dfltsize.cols != 80) fmtok = 0;
  712. if (apiopenreq.dfltsize.ptsize == 12) {
  713.     if (rowmax12 < 24) fmtok = 0;
  714.     if (colmax12 < 80) fmtok = 0;
  715.     }
  716. else if (apiopenreq.dfltsize.ptsize != 9) fmtok = 0;
  717. if (apiopenreq.altsize.rows < 24) fmtok = 0;
  718. if (apiopenreq.altsize.cols < 80) fmtok = 0;
  719. if (apiopenreq.altsize.ptsize == 9) {
  720.     if (rowmax9 < apiopenreq.altsize.rows) fmtok = 0;
  721.     if (colmax9 < apiopenreq.altsize.cols) fmtok = 0;
  722.     }
  723. else if (apiopenreq.altsize.ptsize == 12) {
  724.     if (rowmax12 < apiopenreq.altsize.rows) fmtok = 0;
  725.     if (colmax12 < apiopenreq.altsize.cols) fmtok = 0;
  726.     }
  727. else fmtok = 0;
  728. if (fmtok == 0) {
  729.     apiopenerr(openFormatErr, 0);
  730.     return;
  731.     }
  732.  
  733. newlogin(1, 0, 0, 0, 0);            /* new login with apiopen true */
  734. }
  735.  
  736. void apiopenerr(short code, cnr *cp)
  737. {
  738. if (cp != 0) cp->apiopen = 0;
  739. apiopenresp(code, cp);
  740. }
  741.  
  742. void apiopenresp(short code, cnr *cp)
  743. {
  744. OpenResponse or;
  745. OSErr rc;
  746. unsigned long respid;
  747. short len;
  748.  
  749. memset(&or, 0, sizeof(OpenResponse));
  750. or.msgtype = OpenResponseType;
  751. or.code = code;
  752. if ((code == open3270Mode) || (code == openLineMode)) {
  753.     if (smgr_sppc) {
  754.         or.sppcrefnum = cp->sessrefnum;
  755.         if (cp->sppcname != 0) {
  756.             len = strlen(cp->sppcname);
  757.             if (len > 8) len = 8;
  758.             memcpy(or.sppcname, cp->sppcname, len+1);
  759.             }
  760.         }
  761.     if (smgrppc) {
  762.         or.ppcportnum = cp->sesspref;
  763.         if (cp->ppcname != 0) {
  764.             len = strlen(cp->ppcname);
  765.             if (len > 20) len = 20;
  766.             memcpy(or.ppcname, cp->ppcname, len+1);
  767.             }
  768.         }
  769.     }
  770. memcpy(*sndMessage, &or, sizeof(OpenResponse));
  771.  
  772. /* restore message information */
  773. if (cp != 0) {
  774.     fromrefnum = cp->apiopenrefnum;
  775.     msgId = cp->apiopenmsgid;
  776.     apimsgkind = cp->apiopenkind;
  777.     ppcsref = cp->apiopensref;
  778.     }
  779. else {
  780.     fromrefnum = apiopenrefnum;
  781.     msgId = apiopenmsgid;
  782.     apimsgkind = apiopenkind;
  783.     ppcsref = apiopensref;
  784.     }
  785.  
  786. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
  787.              sizeof(OpenResponse), &respid);
  788. if (cp != 0) cp->apiopenpend = 0;
  789. }
  790.  
  791. void sendconnstat(void)
  792. {
  793. GetConnResponse gcr;
  794. unsigned long openid;
  795. OSErr rc;
  796. unsigned long respid;
  797.  
  798. openid = (*((GetConnStatus **)rcvMessage))->openid;
  799. memset(&gcr, 0, sizeof(GetConnResponse));
  800. gcr.msgtype = GetConnResponseType;
  801. gcr.openid = openid;
  802. gcr.statuscode = getconnstat(openid);
  803. if (gcr.statuscode == openBadId) gcr.openid = 0;
  804. memcpy(*sndMessage, &gcr, sizeof(GetConnResponse));
  805. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
  806.              sizeof(GetConnResponse), &respid);
  807. }
  808.  
  809. short getconnstat(unsigned long openid)
  810. {
  811. short i;
  812. cnr *cp;
  813. char cpok;
  814.  
  815. cpok = 0;
  816. for (i=0; i < MAXSESSIONS; i++) {
  817.     cp = cplist[i];
  818.     if (cp != 0) {
  819.         cpok = cp->apiopen && (openid == cp->apiopenmsgid) &&
  820.                (cp->apiopenkind == apimsgkind);
  821.         if (cpok) break;
  822.         }
  823.     }
  824. if (!cpok) return(openBadId);
  825.  
  826. if (cp->apiopenpend == 0) {
  827.     if (cp->logon) return(open3270Mode);
  828.     else return(openLineMode);
  829.     }
  830.  
  831. if (cp->serflg) return(openConnPending);
  832.  
  833. switch(cp->connstate) {
  834.     case 2:
  835.             return(openResPending);
  836.             break;
  837.     case 3:
  838.             return(openConnPending);
  839.             break;
  840.     case 4:
  841.             return(openNegOptions);
  842.             break;
  843.     default:
  844.             return(noError);
  845.             break;
  846.     }
  847. }
  848.  
  849. OSErr apisend(short myRefNum, short toRefNum, 
  850.               unsigned long replyId, Handle theMessage,
  851.               unsigned short msgLength, unsigned long *msgId)
  852. {
  853. PPCParamBlockPtr wbp;
  854. datainfo *dp;
  855. pascal void (*compproc)();
  856. pascal void writeproc();
  857.  
  858. if (apimsgkind == 1) {
  859.     return(SPPCSend(myRefNum, toRefNum, replyId, theMessage,
  860.             msgLength, msgId));
  861.     }
  862. else {
  863.     wbp = newparamblock();
  864.     if (wbp == 0) {
  865.         return(mFulErr);
  866.         }
  867.     dp = newdatablock();
  868.     if (dp == 0) {
  869.         disposparamblock(wbp);
  870.         return(mFulErr);
  871.         }
  872.     memset(wbp, 0, sizeof(PPCParamBlockRec));
  873.     compproc = writeproc;
  874.     wbp->writeParam.ioCompletion = (PPCCompProcPtr)compproc;
  875.     wbp->writeParam.sessRefNum = ppcsref;
  876.     wbp->writeParam.bufferLength = msgLength;
  877.     wbp->writeParam.bufferPtr = dp->msg;
  878.     apimsgid++;
  879.     wbp->writeParam.userData = apimsgid;
  880.     wbp->writeParam.blockCreator = replyId;
  881.     memset(dp, 0, sizeof(datainfo));
  882.     memcpy(dp->msg, *theMessage, msgLength);
  883.     return(PPCWrite((PPCWritePBPtr)wbp, true));
  884.     }
  885. }
  886.  
  887. pascal void writeproc(PPCParamBlockPtr pb)
  888. {
  889. unsigned char *s;
  890. datainfo * d;
  891.  
  892. s = (unsigned char *)pb->writeParam.bufferPtr;
  893. s -= 24;
  894. d = (datainfo *)s;
  895. disposdatarec(d);
  896. disposparamblock(pb);
  897. }
  898.  
  899. void sessmsg(void)
  900. {
  901. short **msgh;
  902.  
  903. msgh = (short **)rcvMessage;
  904. if (msgLength < 2) {
  905.     senderr(msgcp->sessrefnum, badRequestLength);
  906.     return;
  907.     }
  908.  
  909. switch (**msgh) {
  910.     case GetCharRequestType:
  911.                 if (msgLength != sizeof(GetCharRequest)) {
  912.                     senderr(msgcp->sessrefnum, badRequestLength);
  913.                     return;
  914.                     }
  915.                 sendchar();
  916.                 break;
  917.     case CloseRequestType:
  918.                 if (msgLength != sizeof(CloseRequest)) {
  919.                     senderr(msgcp->sessrefnum, badRequestLength);
  920.                     return;
  921.                     }
  922.                 sessclose(msgcp);
  923.                 break;
  924.     case CloseNotifyRequestType:
  925.                 if (msgLength != sizeof(CloseNotifyRequest)) {
  926.                     senderr(msgcp->sessrefnum, badRequestLength);
  927.                     return;
  928.                     }
  929.                 closenotify();
  930.                 break;
  931.     case GetBuffersRequestType:
  932.                 if (msgLength != sizeof(GetBuffersRequest)) {
  933.                     senderr(msgcp->sessrefnum, badRequestLength);
  934.                     return;
  935.                     }
  936.                 getbuffers();
  937.                 break;
  938.     case WriteNotifyRequestType:
  939.                 if (msgLength != sizeof(WriteNotifyRequest)) {
  940.                     senderr(msgcp->sessrefnum, badRequestLength);
  941.                     return;
  942.                     }
  943.                 writenotify();
  944.                 break;
  945.     case SendDataRequestType:
  946.                 if (msgLength != sizeof(SendDataRequest)) {
  947.                     senderr(msgcp->sessrefnum, badRequestLength);
  948.                     return;
  949.                     }
  950.                 senddatareq();
  951.                 break;
  952.     case SendLocalRequestType:
  953.                 if (msgLength != sizeof(SendLocalRequest)) {
  954.                     senderr(msgcp->sessrefnum, badRequestLength);
  955.                     return;
  956.                     }
  957.                 sendlocal();
  958.                 break;
  959.     default:
  960.                 senderr(msgcp->sessrefnum, badMessageType);
  961.                 break;
  962.     }
  963. }
  964.  
  965. void sendchar(void)
  966. {
  967. GetCharResponse gcr;
  968. OSErr rc;
  969. unsigned long respid;
  970. unsigned char *dest;
  971. short len;
  972.  
  973. memset(&gcr, 0, sizeof(GetCharResponse));
  974. gcr.msgtype = GetCharResponseType;
  975. dest = (*((GetCharRequest **)rcvMessage))->hostname;
  976. if (dest != 0) {
  977.     len = strlen(msgcp->connhostname);
  978.     if (len > 255) len = 255;
  979.     memcpy(dest, msgcp->connhostname, len+1);
  980.     }
  981. dest = (*((GetCharRequest **)rcvMessage))->windowname;
  982. if (dest != 0) {
  983.     len = strlen(msgcp->cswtitle);
  984.     if (len > 127) len = 127;
  985.     memcpy(dest, msgcp->cswtitle, len+1);
  986.     }
  987. gcr.dfltsize.ptsize = msgcp->cs.dfltptsize;
  988. gcr.dfltsize.rows = 24;
  989. gcr.dfltsize.cols = 80;
  990. gcr.altsize.ptsize = msgcp->cs.altptsize;
  991. gcr.altsize.rows = msgcp->cs.altrows;
  992. gcr.altsize.cols = msgcp->cs.altcols;
  993. gcr.linemode = (msgcp->logon == 0);
  994. gcr.hide = msgcp->apihide;
  995. gcr.nowsf = msgcp->cs.ext3270 == 0;
  996. gcr.noalert = msgcp->apinoalert;
  997. memcpy(*sndMessage, &gcr, sizeof(GetCharResponse));
  998. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
  999.         sizeof(GetCharResponse), &respid);
  1000. }
  1001.  
  1002. void sessclose(cnr *cp)
  1003. {
  1004. CloseResponse cr;
  1005. OSErr rc;
  1006. unsigned long respid;
  1007.  
  1008. memset(&cr, 0, sizeof(CloseResponse));
  1009. cr.msgtype = CloseResponseType;
  1010. cr.code = noError;
  1011. memcpy(*sndMessage, &cr, sizeof(CloseResponse));
  1012. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
  1013.         sizeof(CloseResponse), &respid);
  1014. closeresponse(closeAPI, cp);
  1015. if (cp->serflg) serlgout(0, cp);
  1016.     else if (cp->tcpflg) tcplgout(0, cp);
  1017.         else salgout(0, cp);
  1018. }
  1019.  
  1020. void closenotify(void)
  1021. {
  1022. CloseNotifyResponse cnr;
  1023. OSErr rc;
  1024. unsigned long respid;
  1025.  
  1026. memset(&cnr, 0, sizeof(CloseNotifyResponse));
  1027. cnr.msgtype = CloseNotifyResponseType;
  1028. if ((*((CloseNotifyRequest **)rcvMessage))->notifyflag) {
  1029.     if (msgcp->apiclosenotify) {
  1030.         cnr.code = closeNotifyActive;
  1031.         }
  1032.     else {
  1033.         cnr.code = noError;
  1034.         msgcp->apiclosenotify = 1;
  1035.         /* copy request message information */
  1036.         msgcp->apicloserefnum = fromrefnum;
  1037.         msgcp->apiclosemsgid = msgId;
  1038.         msgcp->apiclosekind = apimsgkind;
  1039.         msgcp->apiclosesref = ppcsref;
  1040.         }
  1041.     }
  1042. else {
  1043.     msgcp->apiclosenotify = 0;
  1044.     cnr.code = noError;
  1045.     }
  1046.  
  1047. memcpy(*sndMessage, &cnr, sizeof(CloseNotifyResponse));
  1048. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
  1049.         sizeof(CloseNotifyResponse), &respid);
  1050. }
  1051.  
  1052. void closeresponse(short code, cnr *cp)
  1053. {
  1054. CloseEventResponse cer;
  1055. OSErr rc;
  1056. unsigned long respid;
  1057.  
  1058. if (!cp->apiclosenotify) return;
  1059.  
  1060. memset(&cer, 0, sizeof(CloseEventResponse));
  1061. cer.msgtype = CloseEventResponseType;
  1062. cer.code = code;
  1063.  
  1064. if (smgr_sppc) {
  1065.     cer.sppcrefnum = cp->sessrefnum;
  1066.     }
  1067. if (smgrppc) {
  1068.     cer.ppcportnum = cp->sesspref;
  1069.     }
  1070.  
  1071. memcpy(*sndMessage, &cer, sizeof(CloseEventResponse));
  1072.  
  1073. /* restore message information */
  1074. fromrefnum = cp->apicloserefnum;
  1075. msgId = cp->apiclosemsgid;
  1076. apimsgkind = cp->apiclosekind;
  1077. ppcsref = cp->apiclosesref;
  1078.  
  1079. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
  1080.              sizeof(CloseEventResponse), &respid);
  1081. cp->apiclosenotify = 0;
  1082. }
  1083.  
  1084. void getbuffers(void)
  1085. {
  1086. GetBuffersResponse gbr;
  1087. OSErr rc;
  1088. unsigned long respid;
  1089.  
  1090. memset(&gbr, 0, sizeof(GetBuffersResponse));
  1091. gbr.msgtype = GetBuffersResponseType;
  1092. gbr.databuff = msgcp->chrbuff;
  1093. gbr.attrbuff = msgcp->atrbuff;
  1094. gbr.kblock = &(msgcp->kblock);
  1095. gbr.kblcode = &(msgcp->kblcode);
  1096. gbr.curadr = (unsigned short *)&(msgcp->curadr);
  1097. memcpy(*sndMessage, &gbr, sizeof(GetBuffersResponse));
  1098. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
  1099.         sizeof(GetBuffersResponse), &respid);
  1100. }
  1101.  
  1102. void writenotify(void)
  1103. {
  1104. WriteNotifyResponse wnr;
  1105. OSErr rc;
  1106. unsigned long respid;
  1107.  
  1108. memset(&wnr, 0, sizeof(WriteNotifyResponse));
  1109. wnr.msgtype = WriteNotifyResponseType;
  1110. if ((*((WriteNotifyRequest **)rcvMessage))->notifyflag) {
  1111.     if (msgcp->apiwritenotify) {
  1112.         wnr.code = writeNotifyActive;
  1113.         }
  1114.     else {
  1115.         wnr.code = noError;
  1116.         msgcp->apiwritenotify = 1;
  1117.         /* copy request message information */
  1118.         msgcp->apiwriterefnum = fromrefnum;
  1119.         msgcp->apiwritemsgid = msgId;
  1120.         msgcp->apiwritekind = apimsgkind;
  1121.         msgcp->apiwritesref = ppcsref;
  1122.         }
  1123.     }
  1124. else {
  1125.     msgcp->apiwritenotify = 0;
  1126.     wnr.code = noError;
  1127.     }
  1128.  
  1129. memcpy(*sndMessage, &wnr, sizeof(WriteNotifyResponse));
  1130. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
  1131.         sizeof(WriteNotifyResponse), &respid);
  1132. }
  1133.  
  1134. void writeresponse(unsigned char ccwop, cnr *cp)
  1135. {
  1136. WriteEventResponse wer;
  1137. OSErr rc;
  1138. unsigned long respid;
  1139.  
  1140. if (!(cp->apiwritenotify)) return;
  1141.  
  1142. memset(&wer, 0, sizeof(WriteEventResponse));
  1143. wer.msgtype = WriteEventResponseType;
  1144. wer.ccwop = ccwop;
  1145.  
  1146. if (smgr_sppc) {
  1147.     wer.sppcrefnum = cp->sessrefnum;
  1148.     }
  1149. if (smgrppc) {
  1150.     wer.ppcportnum = cp->sesspref;
  1151.     }
  1152.  
  1153. memcpy(*sndMessage, &wer, sizeof(WriteEventResponse));
  1154.  
  1155. /* restore message information */
  1156. fromrefnum = cp->apiwriterefnum;
  1157. msgId = cp->apiwritemsgid;
  1158. apimsgkind = cp->apiwritekind;
  1159. ppcsref = cp->apiwritesref;
  1160.  
  1161. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
  1162.              sizeof(WriteEventResponse), &respid);
  1163. }
  1164.  
  1165. void senddatareq(void)
  1166. {
  1167. SendDataResponse sdr;
  1168. OSErr rc;
  1169. unsigned long respid;
  1170. unsigned short caddr;
  1171. short length;
  1172. unsigned char *s;
  1173. unsigned char aidcode;
  1174. short i;
  1175. char geflag;
  1176.  
  1177. memset(&sdr, 0, sizeof(SendDataResponse));
  1178. sdr.msgtype = SendDataResponseType;
  1179. length = (*((SendDataRequest **)rcvMessage))->length;
  1180. s = (*((SendDataRequest **)rcvMessage))->data;
  1181.  
  1182. if ((msgcp->connstate == 1) && msgcp->serflg) {    /* serial connection mode */
  1183.     if (length > 0) {
  1184.         for (i=0; i < length; i++) {
  1185.             apisendser(s[i], msgcp);
  1186.             sdr.count++;
  1187.             }
  1188.         }
  1189.     }
  1190. else if (msgcp->tcpflg && (msgcp->connstate == 4)) {
  1191.     if (length > 0) {            /* 3270 line mode */
  1192.         if (msgcp->servermode) {
  1193.             putsrv(s, length, 1, msgcp);
  1194.             }
  1195.         else {
  1196.             if (!(msgcp->hisopts[TELOPT_ECHO])) {
  1197.                 putscr(s, length, 0, msgcp);
  1198.                 }
  1199.             tcpwrite(s, length, msgcp);
  1200.             }
  1201.         sdr.count = length;
  1202.         }
  1203.     }
  1204. else {                            /* 3270 session */
  1205.     caddr = (*((SendDataRequest **)rcvMessage))->curadr;
  1206.     aidcode = (*((SendDataRequest **)rcvMessage))->aidcode;
  1207.                                     /* check for fatal errors */
  1208.     if (msgcp->kblock) {
  1209.         sdr.code = sendLocked;
  1210.         }
  1211.     else if ((caddr != 0xffff) && (caddr > msgcp->maxoff)) {
  1212.         sdr.code = sendBadAddress;        
  1213.         }
  1214.                                     
  1215.     if (sdr.code == noError) {
  1216.                                     /* set cursor address */
  1217.         if (caddr != 0xffff) {
  1218.             msgcp->curadr = caddr;
  1219.             newcur(msgcp);
  1220.             }
  1221.                                     /* store data */
  1222.         if (length > 0) {
  1223.             geflag = 0;
  1224.             msgcp->apikberr = 0;
  1225.             for (i=0; i < length; i++) {
  1226.                 if (s[i] == 0x08) {
  1227.                     geflag = 1;
  1228.                     }
  1229.                 else {
  1230.                     datakey(s[i], geflag, 0, msgcp);
  1231.                     geflag = 0;
  1232.                     if (msgcp->apikberr) {
  1233.                         sdr.code = msgcp->apikberr;
  1234.                         break;
  1235.                         }
  1236.                     else {
  1237.                         sdr.count++;
  1238.                         }
  1239.                     }
  1240.                 }
  1241.             }
  1242.                                     /* send AID */    
  1243.         if ((aidcode != 0) && (sdr.code == noError)) {
  1244.             msgcp->apikberr = 0;
  1245.             attnkey(aidcode, 0, msgcp);
  1246.             sdr.code = msgcp->apikberr;
  1247.             }
  1248.         }
  1249.     }
  1250. sdr.curadr = msgcp->curadr;
  1251. memcpy(*sndMessage, &sdr, sizeof(SendDataResponse));
  1252. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
  1253.         sizeof(SendDataResponse), &respid);
  1254. }
  1255.  
  1256. void apisendser(unsigned char c, cnr *cp)
  1257. {
  1258. if (c == 0x12) {
  1259.     cp->serverflags = 0x01;
  1260.     srvswitch(cp);
  1261.     }
  1262. else {
  1263.     if (cp->servermode) {
  1264.         putsrv(&c, 1, 1, cp);
  1265.         }
  1266.     else {
  1267.         serout(c);
  1268.         }
  1269.     }
  1270. }
  1271.  
  1272. void sendlocal(void)
  1273. {
  1274. SendLocalResponse slr;
  1275. OSErr rc;
  1276. unsigned long respid;
  1277. short length;
  1278. unsigned char *s;
  1279. short i;
  1280.  
  1281. memset(&slr, 0, sizeof(SendLocalResponse));
  1282. slr.msgtype = SendLocalResponseType;
  1283. length = (*((SendLocalRequest **)rcvMessage))->length;
  1284. s = (*((SendLocalRequest **)rcvMessage))->data;
  1285. if (length > 0) {
  1286.                                     /* check for fatal errors */
  1287.     if (msgcp->kblock) {
  1288.         if (s[0] != 13) {
  1289.             slr.code = sendLocked;
  1290.             }
  1291.         }
  1292.     if (slr.code == noError) {
  1293.                                     /* execute operations */
  1294.         msgcp->apikberr = 0;
  1295.         for (i=0; i < length; i++) {
  1296.             funckey(s[i], 0, msgcp);
  1297.             if (msgcp->apikberr) {
  1298.                 slr.code = msgcp->apikberr;
  1299.                 break;
  1300.                 }
  1301.             else {
  1302.                 slr.count++;
  1303.                 }
  1304.             }
  1305.         }
  1306.     }
  1307. slr.curadr = msgcp->curadr;
  1308. memcpy(*sndMessage, &slr, sizeof(SendLocalResponse));
  1309. rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
  1310.         sizeof(SendLocalResponse), &respid);
  1311. }
  1312.